package cn.org.qary.controller.abelianymph.front;

import cn.org.qary.entity.*;
import cn.org.qary.service.trait.abelianymph.CartService;
import cn.org.qary.service.trait.abelianymph.OrderRecordService;
import cn.org.qary.service.trait.abelianymph.OrderService;
import cn.org.qary.service.trait.abelianymph.ProductService;
import cn.org.qary.service.trait.rking.AddressInfoService;
import cn.org.qary.service.trait.rking.UserService;
import io.vavr.Tuple2;
import io.vavr.Tuple3;
import io.vavr.Tuple4;
import io.vavr.Tuple2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

@Controller
@RequestMapping("order")
public class OrderController {

    @Autowired
    OrderService orderService;

    @Autowired
    OrderRecordService orderRecordService;

    @Autowired
    AddressInfoService addressInfoService;

    @Autowired
    UserService userService;

    @Autowired
    HttpSession session;

    @Autowired
    CartService cartService;

    @Autowired
    ProductService productService;


    @RequestMapping("insert")
    public String insert(
            Integer addressInfoId,
            Model model
    ) {
       if (session.getAttribute("token") == null) {
           return "redirect:/index.jsp";
       }

        User user = ((User) session.getAttribute("user"));

        Order order = getReadyOrder();

        order.setUserId(user.getId());

        order.setAddressInfoId(addressInfoId);

        Integer totalPrice = (Integer) session.getAttribute("totalPrice");

        order.setTotal(totalPrice);

        order.setStatus("no_pay");

        orderService.insert(order);

        OrderRecord orderRecord = new OrderRecord();
        System.out.println("order_id:"+ order.getId());

        List<Tuple2<Product, CartRecord>> tuple2List = (List<Tuple2<Product, CartRecord>>) session.getAttribute("tuple2List");

        tuple2List.stream()
                .map(t -> new OrderRecord(null, order.getId(), t._1().getId(), t._2().getAmount()))
                .forEach(or -> orderRecordService.insert(or));

        tuple2List.stream()
                .map(t -> t._2().getId())
                .forEach(id -> cartService.delete(id));

        session.removeAttribute("tuple2List");
        session.removeAttribute("totalPrice");
        session.removeAttribute("token");
        model.addAttribute("order", order);

        return "truesubmit";
    }

    @RequestMapping("display")
    public String display(
            Model model
    ) {
        List<Order> orderList = orderService.selectAll();
        List<Tuple4<Order, AddressInfo, List<Tuple3<Product, OrderRecord, Integer>>, Integer>> tuple4List = orderList.stream()
                .map(o -> new Tuple2<>(o, addressInfoService.selectById(o.getAddressInfoId())))
                .map(t -> {
                    Example example = new Example(OrderRecord.class);
                    Example.Criteria criteria = example.createCriteria();
                    criteria.andEqualTo("orderId", t._1().getId());

                    List<Tuple3<Product, OrderRecord, Integer>> tuple3List1 = orderRecordService.selectByCondition(example)
                            .stream()
                            .map(or -> new Tuple2<>(productService.selectById(or.getProductId()), or))
                            .map(t1 -> new Tuple3<>(t1._1(), t1._2(), Integer.parseInt(t1._1().getPrice()) * t1._2().getAmount()))
                            .collect(Collectors.toList());

                    return new Tuple3<>(t._1(), t._2, tuple3List1);
                })
                .map(t -> {
                    int i1 = t._3().stream()
                            .map(Tuple3::_3)
                            .reduce(0, Integer::sum);

                    return new Tuple4<>(t._1(), t._2(), t._3(), i1);
                })
                .collect(Collectors.toList());

        model.addAttribute("tuple4List", tuple4List);
        return "myorder";
    }

    @RequestMapping("pay")
    public String pay(
            String orderId,
            Integer totalPrice,
            RedirectAttributes redirectAttributes
    ) {
        Order order = orderService.selectById(orderId);
        order.setStatus("pay");
        orderService.update(order);
        redirectAttributes.addAttribute("orderId", orderId);
        redirectAttributes.addAttribute("totalPrice", totalPrice);
        return "redirect:/pay.jsp";
    }

    private Order getReadyOrder() {
        Order order = new Order();
        order.setId(orderService.generateOrderId());
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        now.format(dateTimeFormatter);

        order.setDatetime(now.toString());

        return order;
    }
}
